/**
 * 当元素处于滚动条范围之外时，启用或模拟 position:fixed (jQuery plugin)
 * @author Rox <rox@taomee.com>
 */
(function($) {
    /**
     * 插件入口函数
     * @param {int} top_gap         元素到顶栏的间距(px)
     * @param {int} check_delay     滚动事件触发函数的延迟时间(ms)
     * @param {string} fn_easing    jQuery.animate 的 Easing function 参数(@see: http://api.jquery.com/animate/)
     * @param {boolean} force       是否强制使用模拟方式并启用动画（默认：否，在支持 position:static 的浏览器下只简单地设置元素的样式为 position:static）
     */
    $.fn.set_fixed = function(top_gap, check_delay, fn_easing, force) {
        // 默认参数
        var TOP_GAP     = top_gap || 5;
        var CHECK_DELAY = check_delay || 100;
        var FN_EASING   = fn_easing || 'swing';

        var _this = this;

        // test if browser supports position:fixed
        var supports_fixed = force ? false : (function() {
            try {
                if ( jQuery.browser.msie && parseInt(jQuery.browser.version) < 7 ) return false;

                var tmp = document.getElementsByTagName('script')[0];
                try {
                    tmp.style.position = 'fixed';
                } catch(ex) {}
                if (tmp.currentStyle) {
                    var ret = tmp.currentStyle.position;
                }
                else if (window.getComputedStyle) {
                    var ret = document.defaultView.getComputedStyle(tmp, null).getPropertyValue('position');
                }
                return (ret && (ret == 'fixed'));
            } catch ( ex ) {
                return false;
            }
            return false;
        })();

        // 读取元素相对于 document 顶部的距离，记下
        $.each(_this, function(_, element) {
            $(element).data('offset_top', $(element).offset().top);
        });

        // set/simulate position:fixed
        var fn_set_fixed = function(element, scrollTop) {
            if ( supports_fixed )
            {
                $(element).css('position', 'fixed');
                $(element).css('top', TOP_GAP);
            }
            else
            {
                $(element).css('position', 'absolute').css('opacity', .9);
                $(element).stop().animate({
                    top: scrollTop + TOP_GAP
                }, 'fast', function() {
                    $(this).css('opacity', 1);
                });
            }
        };

        // restore to position:static
        var fn_set_static = function(element, elm_offset_top_orig) {
            if (supports_fixed)
            {
                $(element).css('position', 'static').css('opacity', 1).css('margin-top', 0);
            }
            else
            {
                $(element).stop().animate({
                    'top': elm_offset_top_orig
                }, 'fast', FN_EASING, function() {
                    $(this).css('position', 'static').css('opacity', 1).css('margin-top', 0);
                });
            }
        };

        // 主要功能函数，设置元素样式与位置
        var _do = function(wrapper) {
            var scrollTop = $(wrapper).scrollTop();

            $.each(_this, function(_, element) {
                var elm_offset_top_orig = $(element).data('offset_top');

                window.clearTimeout($(element).data('scroll_timer'));

                if ( scrollTop > elm_offset_top_orig )
                {
                    if ( $(element).outerHeight() >= $.getViewportHeight() )
                    {
                        var offset = $(element).outerHeight() - $.getViewportHeight();
                        $(element).css('margin-top', -offset-TOP_GAP);
                    }
                    else
                    {
                        $(element).css('margin-top', 0);
                    }

                    var timer = window.setTimeout(function() {
                        fn_set_fixed(element, scrollTop);
                    }, CHECK_DELAY);
                    $(element).data('scroll_timer', timer);
                }
                else
                {
                    fn_set_static(element, elm_offset_top_orig);
                }
            });
        };

        // scroll 事件处理（@note: IE 只认 window.onscroll）
        $(window).scroll(function() {
            _do(this);
        });

        // 初始化样式与位置
        _do($(window));
    };
})(jQuery);
